package com.lz.timer.an.config;

import javax.annotation.Resource;

import org.springframework.util.StringUtils;

import com.dangdang.ddframe.job.api.ElasticJob;
import com.dangdang.ddframe.job.api.JobType;
import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
import com.dangdang.ddframe.job.api.script.ScriptJob;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
import com.dangdang.ddframe.job.config.script.ScriptJobConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import com.lz.timer.an.common.Config;

import lombok.extern.slf4j.Slf4j;

/**
 * @author liuzhangcheng
 * @Description: 作业配置
 */
@Slf4j
public class BaseJobConfig {


    /**
     * 注册中心配置
     */
    @Resource
    private ZookeeperRegistryCenter regCenter;

    /**
     * 将作业运行的痕迹进行持久化到DB的操作配置
     */
    @Resource
    private JobEventConfiguration jobEventConfiguration;

    /**
     * 基于Spring的作业启动器
     *
     * @param elasticJob
     * @param jobConfigBean
     * @param elasticJobListeners
     * @return
     */
    protected JobScheduler springJobScheduler(final ElasticJob elasticJob, final BaseJobConfigBean jobConfigBean,
                                              final ElasticJobListener... elasticJobListeners) {

        JobType jobType = null;

        if (elasticJob instanceof ScriptJob) {
            jobType = JobType.SCRIPT;
        } else if (elasticJob instanceof SimpleJob) {
            jobType = JobType.SIMPLE;
        } else if (elasticJob instanceof DataflowJob) {
            jobType = JobType.DATAFLOW;
        }

        log.info("{} , jobConfigBean:{}, elasticJob, elasticJobListeners", jobType, jobConfigBean.toString(),
                elasticJob.toString(), elasticJobListeners);

        if (StringUtils.isEmpty(jobConfigBean.getCron())) {
            jobConfigBean.setCron(Config.JOB_DEF_CRON);
            // 禁止启动
            jobConfigBean.setDisabled(true);
        }

        if (StringUtils.isEmpty(jobConfigBean.getJobName())) {
            jobConfigBean.setJobName(elasticJob.getClass().getName());
        }

        if (StringUtils.isEmpty(jobConfigBean.getJobClass())) {
            jobConfigBean.setJobClass(elasticJob.getClass().getCanonicalName());
        }

        // 作业核心配置.
        JobCoreConfiguration jobCoreConfiguration = getJobCoreConfiguration(jobConfigBean);

        // 作业类型配置.
        JobTypeConfiguration jobTypeConfiguration = getJobTypeConfiguration(jobType, jobCoreConfiguration, jobConfigBean);

        // Lite作业配置.
        LiteJobConfiguration liteJobConfiguration = getLiteJobConfiguration(jobTypeConfiguration, jobConfigBean);

        // 基于Spring的作业启动器.
        return new SpringJobScheduler(elasticJob, regCenter, liteJobConfiguration, jobEventConfiguration, elasticJobListeners);
    }

    /**
     * 获取作业核心配置
     *
     * @param jobConfigBean
     * @return
     */
    private JobCoreConfiguration getJobCoreConfiguration(BaseJobConfigBean jobConfigBean) {
        return JobCoreConfiguration
                .newBuilder(jobConfigBean.getJobName(), jobConfigBean.getCron(), jobConfigBean.getShardingTotalCount())
                .shardingItemParameters(jobConfigBean.getShardingItemParameters())
                .description(jobConfigBean.getDescription())
                .jobParameter(jobConfigBean.getJobParameter())
                .failover(jobConfigBean.isFailover())
                .misfire(jobConfigBean.isMisfire())
                .build();
    }

    /**
     * 获取作业类型配置
     *
     * @param jobType
     * @param jobCoreConfiguration
     * @param jobConfigBean
     * @return
     */
    private JobTypeConfiguration getJobTypeConfiguration(JobType jobType, JobCoreConfiguration jobCoreConfiguration,
                                                         BaseJobConfigBean jobConfigBean) {
        switch (jobType) {
            case DATAFLOW:
                return new DataflowJobConfiguration(jobCoreConfiguration, jobConfigBean.getJobClass(), jobConfigBean.isStreamingProcess());
            case SIMPLE:
                return new SimpleJobConfiguration(jobCoreConfiguration, jobConfigBean.getJobClass());
            case SCRIPT:
                return new ScriptJobConfiguration(jobCoreConfiguration, jobConfigBean.getScriptCommandLine());
            default:
                return null;
        }

    }

    /**
     * Lite作业配置
     *
     * @param jobTypeConfiguration
     * @param jobConfigBean
     * @return
     */
    private LiteJobConfiguration getLiteJobConfiguration(JobTypeConfiguration jobTypeConfiguration, BaseJobConfigBean jobConfigBean) {
        // Lite作业配置. overwrite:设置本地配置是否可覆盖注册中心配置.
        // 作业配置分为3级，分别是JobCoreConfiguration，JobTypeConfiguration和LiteJobConfiguration。
        // LiteJobConfiguration使用JobTypeConfiguration，JobTypeConfiguration使用JobCoreConfiguration，层层嵌套。
        // JobTypeConfiguration根据不同实现类型分为SimpleJobConfiguration，DataflowJobConfiguration和ScriptJobConfiguration。
        return LiteJobConfiguration.newBuilder(jobTypeConfiguration)
                .overwrite(jobConfigBean.isOverwrite())
                .disabled(jobConfigBean.isDisabled())
                .monitorPort(jobConfigBean.getMonitorPort())
                .monitorExecution(jobConfigBean.isMonitorExecution())
                .reconcileIntervalMinutes(jobConfigBean.getReconcileIntervalMinutes())
                .build();
    }


}
